package com.ihg.hiex.admin.handler.impl;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.demo2do.core.entity.exception.BusinessException;
import com.ihg.hiex.admin.handler.ZipHandler;
import com.ihg.hiex.entity.session.after.SessionReport;

/**
 * 
 * @author mohanlan
 *
 */
@Component("zipHandler")
public class ZipHandlerImpl implements ZipHandler {
    
    private static final Logger logger = LoggerFactory.getLogger(ZipHandlerImpl.class);
    
    @Value("#{config['cloud.path']}")
    private String cloudpath;
    
    @Value("#{cloud['cloud.host']}")
    private String cloudhost;
    
    static final int BUFFER = 8192;
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.handler.ZipHandler#zipFile(java.lang.String, java.lang.String, com.ihg.hiex.entity.session.SessionReport)
     */
    public String zipFile(String path, String zipname, SessionReport sessionReport) throws Exception {
        
          FileOutputStream fOutputStream = this.initZip(cloudpath + "/" + path, zipname);
          ZipOutputStream zoutput = new ZipOutputStream(fOutputStream);
          
          InputStream waveInputStream = this.getWaveDelegateReportFile(sessionReport);
          InputStream managerInputStream = this.getManagerReportFile(sessionReport);
          
          String waveReportName = this.generateWaveDelegateReportName(sessionReport);
          String managerReportName = this.generateManagerReportName(sessionReport);
          
          this.writeFile(zoutput, waveInputStream, waveReportName);
          this.writeFile(zoutput, managerInputStream, managerReportName);
                  
          zoutput.closeEntry();
          zoutput.close();
          fOutputStream.close();
          
          return cloudhost + "/" + path + "/" + zipname + ".zip";
        
    }
    
    /**
     * 
     * @param path
     * @param filename
     * @param targetFolder
     * @param zipname
     * @return
     * @throws Exception
     */
    private FileOutputStream initZip(String path, String zipname) throws Exception{
        String zipFullName = path == null ? zipname : (path + "/" + zipname);
        
        File file = new File(zipFullName + ".zip");
        if(!file.exists()) {
            file.createNewFile();
            logger.trace("#initZip - create zip file with name [{name}]", file.getName());
        }
        
        FileOutputStream fOutputStream = new FileOutputStream(file);
        return fOutputStream;
    }
    
    /**
     * 
     * @param zoutput
     * @param inputStream
     * @param qrcodeName
     * @throws IOException
     */
    private void writeFile(ZipOutputStream zoutput, InputStream inputStream, String qrcodeName) throws IOException {
        // put file to zip
        zoutput.putNextEntry(new ZipEntry(qrcodeName));
        logger.trace("#writeFile - put file into zipFile with name [{qrcodeName}]", qrcodeName);
        
        BufferedInputStream bis = new BufferedInputStream(inputStream);
        
        int count;
        byte data[] = new byte[BUFFER];
        while ((count = bis.read(data, 0, BUFFER)) != -1) {  
                zoutput.write(data, 0, count);  
        }  
        logger.trace("#writeFile - write qrcode image to zip");
        bis.close();
    }
    
    /**
     * 
     * @param sessionReport
     * @return
     */
    private InputStream getWaveDelegateReportFile(SessionReport sessionReport) {
        
        InputStream inputStream;
        
        try {
            
            String[] waveDelegateReport = StringUtils.splitByWholeSeparator(sessionReport.getWaveDelegateReport(),"/report/");
            String fileName = waveDelegateReport[1];
            
            logger.info("#getWaveDelegateReportFile() start get waveDelegateReport with fileName[{}]", fileName);
            
            File qrcode = new File(cloudpath + "/" + sessionReport.getSession().getName() + "/" + sessionReport.getDelegate().getName() + "/report", fileName);
            inputStream = new FileInputStream(qrcode);
            
        } catch (FileNotFoundException e) {
            logger.error("#getWaveDelegateReportFile() error");
            throw new BusinessException("获取wave delegate report 失败");
        }
        
        return inputStream;
    }
    
    /**
     * 
     * @param sessionReport
     * @return
     */
    private InputStream getManagerReportFile(SessionReport sessionReport) {
        
        InputStream inputStream;
        
        try {
            
            String[] managerReport = sessionReport.getManagerFinalReport().split("/report/");
            String fileName = managerReport[1];
            
            logger.info("#getManagerReportFile() start get managerReport with fileName[{}]", fileName);
            
            File qrcode = new File(cloudpath + "/" + sessionReport.getSession().getName() + "/" + sessionReport.getDelegate().getName() + "/report", fileName);
            inputStream = new FileInputStream(qrcode);
            
        } catch (FileNotFoundException e) {
            logger.error("#getManagerReportFile() error");
            throw new BusinessException("获取managerReport 失败");
        }
        
        return inputStream;
    }
    
    /**
     * 
     * @param sessionReport
     * @return
     */
    private String generateWaveDelegateReportName(SessionReport sessionReport) {
        String[] waveDelegateReport = sessionReport.getWaveDelegateReport().split("/report/");
        
//        return cloudpath + "/" + sessionReport.getSession().getName() + "/" + sessionReport.getDelegate().getName() + "/report/" + waveDelegateReport[1];
        return waveDelegateReport[1];
    }
    
    /**
     * 
     * @param sessionReport
     * @return
     */
    private String generateManagerReportName(SessionReport sessionReport) {
        String[] managerReport = sessionReport.getManagerFinalReport().split("/report/");
        
//        return cloudpath + "/" + sessionReport.getSession().getName() + "/" + sessionReport.getDelegate().getName() + "/report/" + managerReport[1];
        return managerReport[1];
    }
    
}
